package cn.sunxyz.base.component;

import cn.sunxyz.base.common.BoolPair;

import static cn.sunxyz.base.logicgate.LogicGate.*;

/**
 * Created by yangrd on 2017/6/28.
 */
public class Adder {

    public static boolean[] add(boolean[] bs1, boolean[] bs2) {
        if (bs1.length != bs2.length) {
            throw new IllegalArgumentException();
        }
        boolean c = false;
        boolean[] result = new boolean[bs1.length + 1];
        for (int i = bs1.length - 1; i > -1; i--) {
            BoolPair boolPair = adder(bs1[i], bs2[i], c);
            result[i + 1] = boolPair.first;
            c = boolPair.last;
        }
        if (c == false) {
            boolean[] result2 = new boolean[bs1.length];
            for (int i = 1; i < result.length; i++) {
                result2[i - 1] = result[i];
            }
            return result2;
        }
        result[0] = c;
        return result;
    }

    public static String boolToStr(boolean[] bs) {
        String str = "";
        for (boolean b : bs) {
            str += (b ? 1 : 0);
        }
        return str;
    }

    private static BoolPair adder(boolean a, boolean b, boolean carry) {
        BoolPair boolPair1 = halfAdder(a, b);
        BoolPair boolPair2 = halfAdder(carry, boolPair1.first);
        boolean sum = boolPair2.first;
        boolean c = or(boolPair1.last, boolPair2.last);
        return BoolPair.of(sum, c);
    }

    private static BoolPair halfAdder(boolean a, boolean b) {
        boolean sum = xOr(a, b);
        boolean carry = and(a, b);
        return BoolPair.of(sum, carry);
    }


    public static void main(String[] args) {
//        System.out.println(adder(true, true, false));
        boolean[] bs1 = {true, true, true};//110
        boolean[] bs2 = {true, true, false};//110
        //111+110 = 1101
        boolean[] result = add(bs1, bs2);

        System.out.println(boolToStr(result));

//        System.out.println(adder(false, false, adder(true, true, false).last));
    }
}
